/**
 * 飞书自动打卡脚本
 * 功能：
 * 1. 解锁设备并输入密码
 * 2. 打开飞书应用
 * 3. 点击工作台
 * 4. 点击考勤打卡
 */

// 配置常量
var CONFIG = {
    PASSWORD: "123456",
    APP_NAME: "飞书",
    WORKBENCH_TEXT: "工作台",
    ATTENDANCE_TEXT: "假勤",
    WAIT_TIMES: {
        UNLOCK: 1000,
        APP_LAUNCH: 2000,
        WORKBENCH: 2000,
        ATTENDANCE: 2000,
        ELEMENT_FIND: 5000
    },
    SWIPE_DURATION: 500,
    MAX_RETRY: 3
};

/**
 * 日志记录函数
 * @param {string} message 日志消息
 * @param {string} level 日志级别 (info, warn, error)
 */
function log(message, level) {
    level = level || 'info';
    var timestamp = new Date().toLocaleTimeString();
    var prefix = "[" + timestamp + "] [" + level.toUpperCase() + "]";
    console.log(prefix + " " + message);
}

/**
 * 安全点击函数，带重试机制
 * @param {number} x X坐标
 * @param {number} y Y坐标
 * @param {string} description 点击描述
 * @returns {boolean} 是否点击成功
 */
function safeClick(x, y, description) {
    description = description || '';
    try {
        click(x, y);
        log("点击成功: " + description + " (" + x + ", " + y + ")");
        return true;
    } catch (error) {
        log("点击失败: " + description + " - " + error.message, 'error');
        return false;
    }
}

/**
 * 安全查找元素，带超时和重试
 * @param {Object} selector 选择器
 * @param {number} timeout 超时时间
 * @param {number} retries 重试次数
 * @returns {Object|null} 找到的元素或null
 */
function safeFindElement(selector, timeout, retries) {
    timeout = timeout || CONFIG.WAIT_TIMES.ELEMENT_FIND;
    retries = retries || CONFIG.MAX_RETRY;
    for (var i = 0; i < retries; i++) {
        try {
            var element = selector.findOne(timeout);
            if (element) {
                log("找到元素: " + selector.toString());
                return element;
            }
        } catch (error) {
            log('查找元素失败 (尝试 ' + (i + 1) + '/' + retries + '): ' + error.message, 'warn');
        }
        if (i < retries - 1) {
            sleep(1000);
        }
    }
    log('未找到元素: ' + selector.toString(), 'error');
    return null;
}

/**
 * 解锁设备
 * @returns {boolean} 是否解锁成功
 */
function unlockDevice() {
    try {
        log("开始解锁设备");
        // 唤醒设备
        device.wakeUpIfNeeded();
        sleep(CONFIG.WAIT_TIMES.UNLOCK);

        // 上划屏幕解锁
        var height = device.height;
        var width = device.width;
        swipe(width / 2, height - 100, width / 2, 100, CONFIG.SWIPE_DURATION);
        sleep(CONFIG.WAIT_TIMES.UNLOCK);

        // 输入密码
        // if (CONFIG.PASSWORD) {
        //     setText(CONFIG.PASSWORD);
        //     sleep(500);
        //     // 点击确认或回车
        //     keycode("KEYCODE_ENTER");
        //     sleep(CONFIG.WAIT_TIMES.UNLOCK);
        // }

        // 返回主屏幕
        back();
        log("设备解锁成功");
        return true;
    } catch (error) {
        log('设备解锁失败: ' + error.message, 'error');
        return false;
    }
}

/**
 * 打开飞书应用
 * @returns {boolean} 是否打开成功
 */
function openFeishuApp() {
    try {
        log("开始打开飞书应用");
        launchApp(CONFIG.APP_NAME);
        sleep(CONFIG.WAIT_TIMES.APP_LAUNCH);
        log("飞书应用打开成功");
        return true;
    } catch (error) {
        log('打开飞书应用失败: ' + error.message, 'error');
        return false;
    }
}

/**
 * 点击工作台
 * @returns {boolean} 是否点击成功
 */
function clickWorkbench() {
    try {
        log("开始查找工作台");
        var workbench = safeFindElement(text(CONFIG.WORKBENCH_TEXT));

        if (!workbench) {
            log("未找到工作台元素", 'error');
            return false;
        }

        var workbenchRect = workbench.bounds();
        if (workbenchRect) {
            var x = workbenchRect.centerX();
            var y = workbenchRect.centerY();
            var success = safeClick(x, y, "工作台");
            if (success) {
                sleep(CONFIG.WAIT_TIMES.WORKBENCH);
                return true;
            }
        }
        return false;
    } catch (error) {
        log('点击工作台失败: ' + error.message, 'error');
        return false;
    }
}

/**
 * 点击考勤打卡
 * @returns {boolean} 是否点击成功
 */
function clickAttendance() {
    try {
        log("开始查找考勤打卡");
        sleep(CONFIG.WAIT_TIMES.ATTENDANCE);

        // 查找包含"假勤"文本的 ViewGroup
        var viewGroups = className("android.view.ViewGroup").find();

        for (var i = 0; i < viewGroups.length; i++) {
            var viewGroup = viewGroups[i];
            var textViews = viewGroup.find(className("android.widget.TextView"));

            for (var j = 0; j < textViews.length; j++) {
                if (textViews[j].text() && textViews[j].text().includes(CONFIG.ATTENDANCE_TEXT)) {
                    log("找到考勤打卡元素");

                    // 尝试点击当前ViewGroup
                    if (viewGroup.clickable()) {
                        viewGroup.click();
                        log("成功点击考勤打卡");
                        return true;
                    }

                    // 向上查找可点击的父级
                    var parent = viewGroup.parent();
                    while (parent) {
                        if (parent.clickable() && parent.className() === "android.view.ViewGroup") {
                            parent.click();
                            log("成功点击考勤打卡父级");
                            return true;
                        }
                        parent = parent.parent();
                    }
                }
            }
        }

        log("未找到可点击的考勤打卡元素", 'error');
        return false;
    } catch (error) {
        log('点击考勤打卡失败: ' + error.message, 'error');
        return false;
    }
}

/**
 * 主执行函数
 * @returns {boolean} 是否执行成功
 */
function executeAttendanceCheck() {
    log("开始执行自动打卡流程");

    // 检查是否为工作日
    if (!isWorkday()) {
        log("今天不是工作日，跳过打卡", 'warn');
        return false;
    }

    try {
        // 1. 解锁设备
        if (!unlockDevice()) {
            log("设备解锁失败，终止执行", 'error');
            return false;
        }

        // 2. 打开飞书应用
        if (!openFeishuApp()) {
            log("打开飞书应用失败，终止执行", 'error');
            return false;
        }

        // 3. 点击工作台
        if (!clickWorkbench()) {
            log("点击工作台失败，终止执行", 'error');
            return false;
        }

        // 4. 点击考勤打卡
        if (!clickAttendance()) {
            log("点击考勤打卡失败，终止执行", 'error');
            return false;
        }

        log("自动打卡流程执行完成");
        sleep(2000);

        // 息屏
        sleep(1000);
        return true;

    } catch (error) {
        log('执行过程中发生错误: ' + error.message, 'error');
        return false;
    }
}

/**
 * 判断是否为工作日
 * @returns {boolean} 是否为工作日
 */
function isWorkday() {
    var today = new Date();
    var dayOfWeek = today.getDay(); // 0=周日, 1=周一, ..., 6=周六
    var weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
    var isWork = dayOfWeek >= 1 && dayOfWeek <= 5; // 周一到周五为工作日

    log("今天是 " + weekDays[dayOfWeek] + (isWork ? " (工作日)" : " (休息日)"));
    return isWork;
}

/**
 * 定时执行函数
 * @param {number} hour 执行小时
 * @param {number} minute 执行分钟
 * @param {number} second 执行秒数
 */
function scheduleAttendanceCheck(hour, minute, second) {
    hour = hour || 9;
    minute = minute || 0;
    second = second || 0;
    var minuteStr = minute < 10 ? '0' + minute : minute.toString();
    var secondStr = second < 10 ? '0' + second : second.toString();
    log('设置定时打卡: ' + hour + ':' + minuteStr + ':' + secondStr);

    var hasExecuted = false;

    var intervalId = setInterval(function () {
        var currentTime = new Date();
        var currentHour = currentTime.getHours();
        var currentMinute = currentTime.getMinutes();
        var currentSecond = currentTime.getSeconds();

        var currentMinuteStr = currentMinute < 10 ? '0' + currentMinute : currentMinute.toString();
        var currentSecondStr = currentSecond < 10 ? '0' + currentSecond : currentSecond.toString();
        log('当前时间: ' + currentHour + ':' + currentMinuteStr + ':' + currentSecondStr);

        // 检查是否到达执行时间
        if (currentHour === hour && currentMinute === minute && currentSecond === second) {
            if (!hasExecuted) {
                // 检查是否为工作日
                if (isWorkday()) {
                    log("到达定时执行时间，开始执行打卡");
                    executeAttendanceCheck();
                    hasExecuted = true;
                } else {
                    log("今天不是工作日，跳过打卡");
                    hasExecuted = true; // 标记为已执行，避免重复检查
                }
            }
        }

        // 如果已经过了执行时间5分钟，重置标志
        if (currentHour === hour && currentMinute > minute + 5) {
            hasExecuted = false;
            log("重置执行标志，等待下次执行");
        }

        // 如果已经过了执行时间1小时，停止定时器
        if (currentHour > hour) {
            log("停止定时器");
            clearInterval(intervalId);
        }
    }, 1000);

    return intervalId;
}

/**
 * 定时执行函数（支持多个时间点）
 * @param {Array} timeList 例如：[{hour:9,minute:0,second:0},{hour:18,minute:0,second:0}]
 */
function scheduleAttendanceCheckMulti(timeList) {
    // 标记每天每个时间点是否已执行
    var executedFlags = timeList.map(() => false);
    var lastDay = (new Date()).getDate();

    setInterval(function () {
        var now = new Date();
        var currentHour = now.getHours();
        var currentMinute = now.getMinutes();
        var currentSecond = now.getSeconds();

        // 每天零点重置
        if (now.getDate() !== lastDay) {
            executedFlags = timeList.map(() => false);
            lastDay = now.getDate();
            log("新的一天，重置所有时间点执行标志");
        }

        // 检查每个时间点
        for (var i = 0; i < timeList.length; i++) {
            var t = timeList[i];
            if (
                currentHour === t.hour &&
                currentMinute === t.minute &&
                currentSecond === t.second &&
                !executedFlags[i]
            ) {
                if (isWorkday()) {
                    log("到达定时执行时间[" + t.hour + ":" + t.minute + ":" + t.second + "]，开始执行打卡");
                    executeAttendanceCheck();
                } else {
                    log("今天不是工作日，跳过打卡");
                }
                executedFlags[i] = true;
            }
        }
    }, 1000);
}

// 主程序入口
function main() {
    log("飞书自动打卡脚本启动");

    // 显示当前日期和星期信息
    var today = new Date();
    var dateStr = today.getFullYear() + "-" + (today.getMonth() + 1) + "-" + today.getDate();
    log("当前日期: " + dateStr);

    // 检查是否为工作日
    isWorkday();

    // 直接执行一次打卡（用于测试）
    // executeAttendanceCheck();

    // 定时执行（支持多个时间点）
    // 例如：每天9:00:00和18:02:00各执行一次
    scheduleAttendanceCheckMulti([
        { hour: 9, minute: 0, second: 0 },
        { hour: 18, minute: 2, second: 0 }
    ]);
}

// 启动主程序
main();